/*
	This file is part of AVRCppLib.

    AVRCppLib is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    AVRCppLib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with AVRCppLib.  If not, see <http://www.gnu.org/licenses/>.

    Copyright (C) Maxime Lemonnier 2007-2011
 */

#ifndef CallbackServersTest_H_
#define CallbackServersTest_H_

#include "TestCase.h"
#include "Coms/USART/USARTHardware.h"
#include "CallbackServers/DictionnaryCallbackServer.h"
#include "CallbackServers/FastCallbackServer.h"
#include <stdio.h>

#include "MockCallback.h"

using Coms::USART::USARTHardware;

class CallbackServersTest : public TestCase<CallbackServersTest>
{
public:

	CallbackServersTest(const prog_mem * testMethodName_P, TestCase<CallbackServersTest>::TestMethod testMethod) :
	TestCase<CallbackServersTest>(testMethodName_P, testMethod)
	{
		usartHardware = USARTHardware::getUSARTHardware(1);

	}

	~CallbackServersTest()
	{
	}

	bool testDictionnaryCallbackServer()
	{

		MockCallback * mockCallback = new MockCallback();
		DictionnaryCallbackServer::getInstance()->connect(USART1_UDRE_vect, mockCallback);
		usartHardware->enableTransmitter();
		usartHardware->enableTransmitterReadyInterrupts();

		bool result = AVRUNIT_ASSERT(!mockCallback->calledBack);

		enableInterrupts();
		delay(1);
		disableInterrupts();

		result &= AVRUNIT_ASSERT(mockCallback->calledBack);



		usartHardware->disableTransmitter();
		usartHardware->disableTransmitterReadyInterrupts();

		DictionnaryCallbackServer::getInstance()->disconnect(USART1_UDRE_vect);
		delete mockCallback;
		return result;
	}

	bool testFastCallbackServer()
	{
		MockCallback * mockCallback = new MockCallback();
		FastCallbackServer::getInstance()->connect(30, mockCallback);
		usartHardware->enableTransmitter();
		usartHardware->enableReceiver();
		usartHardware->enableFrameReceivedInterrupts();

		bool result = AVRUNIT_ASSERT(!mockCallback->calledBack);

		enableInterrupts();
		usartHardware->writeFrame('a');

		while(!usartHardware->isFrameReceived());
		disableInterrupts();

		result &= AVRUNIT_ASSERT(mockCallback->calledBack);



		usartHardware->disableTransmitter();
		usartHardware->disableReceiver();
		usartHardware->disableFrameReceivedInterrupts();


		FastCallbackServer::getInstance()->disconnect(30);
		delete mockCallback;
		return result;
	}


private:
	USARTHardware * usartHardware;
};



#endif /* CallbackServersTest_H_ */
